<template>
	<div :class="prefixCls" class="flex px-2 py-1.5 items-center">
		<slot name="headerTitle" v-if="slots.headerTitle"></slot>
		<BasicTitle :helpMessage="helpMessage" v-if="!slots.headerTitle && title">
			{{ title }}
		</BasicTitle>
		<div class="flex items-center flex-1 cursor-pointer justify-self-stretch" v-if="search || toolbar">
			<div :class="getInputSearchCls" v-if="search">
				<InputSearch placeholder="搜索..." size="small" allowClear v-model:value="searchValue" />
			</div>
			<Dropdown @click.prevent v-if="toolbar">
				<Icon icon="ion:ellipsis-vertical" />
				<template #overlay>
					<Menu @click="handleMenuClick">
						<template v-for="item in toolbarList" :key="item.value">
							<MenuItem v-bind="{ key: item.value }">
								{{ item.label }}
							</MenuItem>
							<MenuDivider v-if="item.divider" />
						</template>
					</Menu>
				</template>
			</Dropdown>
		</div>
	</div>
</template>
<script lang="ts" setup>
import { computed, ref, watch, useSlots } from 'vue';
import { Dropdown, Menu, MenuItem, MenuDivider, InputSearch } from 'ant-design-vue';
import { Icon } from '#/Icon';
import { BasicTitle } from '#/Basic';
import { useDebounceFn } from '@vueuse/core';
import { ToolbarEnum } from '../types/tree';
import { useDesign } from '@/hooks/web/useDesign';
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';

const searchValue = ref('');

const { prefixCls } = useDesign('tree-header');

const props = defineProps({
	helpMessage: {
		type: [String, Array] as PropType<string | string[]>,
		default: '',
	},
	title: {
		type: String,
		default: '',
	},
	toolbar: {
		type: Boolean,
		default: false,
	},
	checkable: {
		type: Boolean,
		default: false,
	},
	search: {
		type: Boolean,
		default: false,
	},
	searchText: {
		type: String,
		default: '',
	},
	checkAll: {
		type: Function,
		default: undefined,
	},
	expandAll: {
		type: Function,
		default: undefined,
	},
} as const);
const emit = defineEmits(['strictly-change', 'search']);

const slots = useSlots();

const getInputSearchCls = computed(() => {
	const titleExists = slots.headerTitle || props.title;
	return [
		'mr-1',
		'w-full',
		{
			['ml-5']: titleExists,
		},
	];
});

const toolbarList = computed(() => {
	const { checkable } = props;
	const defaultToolbarList = [
		{ label: '展开全部', value: ToolbarEnum.EXPAND_ALL },
		{
			label: '折叠全部',
			value: ToolbarEnum.UN_EXPAND_ALL,
			divider: checkable,
		},
	];

	return checkable
		? [
				{ label: '选择全部', value: ToolbarEnum.SELECT_ALL },
				{
					label: '取消选择',
					value: ToolbarEnum.UN_SELECT_ALL,
					divider: checkable,
				},
				...defaultToolbarList,
				{ label: '层级关联', value: ToolbarEnum.CHECK_STRICTLY },
				{ label: '层级独立', value: ToolbarEnum.CHECK_UN_STRICTLY },
		  ]
		: defaultToolbarList;
});

function handleMenuClick(e: MenuInfo) {
	const { key } = e;
	switch (key) {
		case ToolbarEnum.SELECT_ALL:
			props.checkAll?.(true);
			break;
		case ToolbarEnum.UN_SELECT_ALL:
			props.checkAll?.(false);
			break;
		case ToolbarEnum.EXPAND_ALL:
			props.expandAll?.(true);
			break;
		case ToolbarEnum.UN_EXPAND_ALL:
			props.expandAll?.(false);
			break;
		case ToolbarEnum.CHECK_STRICTLY:
			emit('strictly-change', false);
			break;
		case ToolbarEnum.CHECK_UN_STRICTLY:
			emit('strictly-change', true);
			break;
	}
}

function emitChange(value?: string): void {
	emit('search', value);
}

const debounceEmitChange = useDebounceFn(emitChange, 200);

watch(
	() => searchValue.value,
	v => {
		debounceEmitChange(v);
	},
);

watch(
	() => props.searchText,
	v => {
		if (v !== searchValue.value) {
			searchValue.value = v;
		}
	},
);
</script>
